package com.ruoyi.system.handler;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.RTTCalculator;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.baidu.BaiduMapUtil;
import com.ruoyi.common.utils.baidu.GeoUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.impl.ReceDataServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.ZoneId;
import java.util.List;
import java.util.Map;

/**
 * @author: jkk
 * @create: 2025/3/22-17:06
 * @Description:
 */
@Service
public class ReceDataServiceHandler {

    private static final Logger logger = LoggerFactory.getLogger(ReceDataServiceHandler.class);

    @Autowired
    TLocationDataMapper tLocationDataMapper;

    @Autowired
    private TLogisticsOrderInfoMapper tLogisticsOrderInfoMapper;

    @Autowired
    private AboardAreaMapper aboardAreaMapper;

    @Autowired
    private TWaybillTrackeMapper tWaybillTrackeMapper;

    @Autowired
    private TGeofenceMapper tGeofenceMapper;

    @Autowired
    private RedisCache redisCache;
    @Async("taskExecutor")
    public void processPositionAsync(Map<String, Object> map) {
        try {
            TLocationData tLocationData = new TLocationData();
            if (map.get("id") != null) {
                tLocationData.setDeviceNumber(map.get("id").toString());
            }
            //将时间戳转换为时间
            // 将时间戳转换为时间
            String timestampStr = map.get("timestamp") != null ? map.get("timestamp").toString() : null;
            if (timestampStr != null) {
                try {
                    long timestamp = Long.parseLong(timestampStr);
                    // 假设时间戳是秒为单位，转换为毫秒
                    tLocationData.setCaptureTime(new java.util.Date(timestamp * 1000));
                } catch (NumberFormatException e) {
                    // 处理或记录日志，避免程序因无效的时间戳而崩溃
                    System.err.println("Invalid timestamp format: " + timestampStr);
                }
            }
            if (map.get("lat") != null && map.get("lon") != null) {
                try {
                    String result = BaiduMapUtil.coordinateConversion(map.get("lat").toString(), map.get("lon").toString());
                    if(StringUtils.isNotEmpty(result)){
                        JSONObject jsonObject = JSONObject.parseObject(result);
                        tLocationData.setLongitude(jsonObject.getString("x"));
                        tLocationData.setLatitude(jsonObject.getString("y"));
                    }
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
            if (map.get("batt") != null) {
                tLocationData.setBattery(map.get("batt").toString());
            }
            //@TODO 温度要根据电阻值要单独处理下
            if (map.get("temperature") != null) {
                double temperature = RTTCalculator.calculateTemperature(Double.parseDouble(map.get("temperature").toString()));
                tLocationData.setTemperature(temperature+"");
            }
            //@TODO 速度要单独处理下,需要缓存上一次这个设备的位置数据
            //if (map.get("speed") != null) {
            TLocationData lastLocationData = (TLocationData)redisCache.getCacheObject(tLocationData.getDeviceNumber());
            if(lastLocationData != null){
                double distance = BaiduMapUtil.calculateDistance(
                        Double.parseDouble(lastLocationData.getLatitude()),
                        Double.parseDouble(lastLocationData.getLongitude()),
                        Double.parseDouble(tLocationData.getLatitude()),
                        Double.parseDouble(tLocationData.getLongitude()));
                tLocationData.setSpeed(BaiduMapUtil.calculateAverageSpeed(
                        distance, lastLocationData.getCaptureTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(),
                        tLocationData.getCaptureTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime())+"");
                //判断是否移动
                if(distance >0){
                    tLocationData.setIsMove("1");
                }else {
                    tLocationData.setIsMove("0");
                }
            }else {
                redisCache.setCacheObject(tLocationData.getDeviceNumber(), tLocationData);
                tLocationData.setSpeed("0");
            }
            //}
            //存储yyyy-MM-dd格式的日期
            tLocationData.setDateOfDay(DateUtils.getDate());

            //@TODO 获取地理位置信息,国外只能获取到地点信息
            String result = BaiduMapUtil.rerseveGeoCode(tLocationData.getLatitude(),tLocationData.getLongitude());
            if(StringUtils.isNotEmpty(result)){
                JSONObject jsonObject = JSONObject.parseObject(result);
                String address = jsonObject.getString("address");
                String adcode = jsonObject.getString("adcode");
                tLocationData.setCityName(address);
                tLocationData.setCityCode(adcode);
                if("0".equals(adcode)){
                    tLocationData.setCityCode("");
                }
            }
            String deviceName = map.get("deviceName").toString();
            tLocationData.setDeviceName(deviceName);
            tLocationData.setReportInterval(map.get("uploadInterval").toString());
            tLocationData.setLocatWay("1");
            tLocationDataMapper.insertTLocationData(tLocationData);

            List<TLogisticsOrderInfo> list = tLogisticsOrderInfoMapper.
                    selectTLogisticsOrderInfoByDeviceNumber(tLocationData.getDeviceNumber());
            if(list.size() > 0){
                for (TLogisticsOrderInfo tLogisticsOrderInfo : list){
                    TWaybillTracke tWaybillTracke = new TWaybillTracke();
                    String orderNumber = tLogisticsOrderInfo.getOrderNumber();
                    tWaybillTracke.setOrderNumber(orderNumber);
                    //@TODO 获取是否进入某个围栏信息 1 查询口岸围栏数据 2 查询转关地址围栏数据
                    List<TGeofence> tGeofenceList = tGeofenceMapper.selectTGeofenceByOrderId(tLogisticsOrderInfo.getId());
                    if(tGeofenceList.size() > 0){
                        for (TGeofence tGeofence : tGeofenceList){
                            //判断国内口岸围栏
                            String geofenceType = tGeofence.getType();
                            String geofenceData = tGeofence.getArea();
                            if(StringUtils.isNotEmpty(geofenceType)&&
                                    StringUtils.isNotEmpty(geofenceData)){
                                Boolean isInGeofence = GeoUtils.isPointInGeofence(
                                        tLocationData.getLatitude(),
                                        tLocationData.getLongitude(),
                                        geofenceType, geofenceData);
                                if(isInGeofence){
                                    //在哪个围栏内，下发通知
                                    logger.info("设备："+tLocationData.getDeviceNumber()+
                                            " 在订单："+orderNumber+"的"+tGeofence.getName()+"围栏内");
                                }
                            }
                            String geofenceType1 = tGeofence.getTransitPortType();
                            String geofenceData1 = tGeofence.getTransitPortArea();
                            if(StringUtils.isNotEmpty(geofenceType1)&&StringUtils.isNotEmpty(geofenceData1)){
                                Boolean isInGeofence1 = GeoUtils.isPointInGeofence(
                                        tLocationData.getLatitude(),
                                        tLocationData.getLongitude(),
                                        geofenceType1, geofenceData1);
                                if(isInGeofence1){
                                    //在哪个围栏内，下发通知
                                    logger.info("设备："+tLocationData.getDeviceNumber()+
                                            " 在订单："+orderNumber+"的"+tGeofence.getName()+"围栏内");
                                }
                            }
                        }
                    }
                    //@TODO 获取天气信息,需要判断是不是国外的城市，再根据高级方法调用经纬度获取天气
                    //首先判今天的天气获取了没有
                    TWaybillTracke tWaybillTracke1 = tWaybillTrackeMapper.selectTWaybillTrackeByDateOfDay(tLocationData.getDateOfDay());
                    if(tWaybillTracke1 == null){
                        String weather = "";
                        if(StringUtils.isNotEmpty(tLocationData.getCityCode())){
                            weather = BaiduMapUtil.getWeather(tLocationData.getCityCode());
                        }else {
                            //根据经纬度获取国外的天气信息
                            weather = "天气晴 温度25度";
                        }
                        tWaybillTracke.setWeather(weather);
                    }
                    //@TODO 距离信息
                    String destId = tLogisticsOrderInfo.getUnloadingPlaceId();
                    AboardArea aboardArea = aboardAreaMapper.selectAboardAreaByDistrictId(destId);
                    if(aboardArea != null){
                        double distance = BaiduMapUtil.calculateDistance(
                                Double.parseDouble(tLocationData.getLatitude()),
                                Double.parseDouble(tLocationData.getLongitude()),
                                Double.parseDouble(aboardArea.getLat()),
                                Double.parseDouble(aboardArea.getLon()));
                        tWaybillTracke.setDestDistance(distance+"");
                        if(distance <= 400){
                            //发送短信通知
                            logger.info("设备："+tLocationData.getDeviceNumber()+
                                    " 到达目的地："+tLogisticsOrderInfo.getUnloadingPlaceName()+"，距离："+distance+"千米");
                        }
                    }
                    //@TODO 将设备的值传递到运踪的表里
                    tWaybillTracke.setType("1");
                    tWaybillTracke.setDeviceNumber(tLocationData.getDeviceNumber());
                    tWaybillTracke.setLongitude(tLocationData.getLongitude());
                    tWaybillTracke.setLatitude(tLocationData.getLatitude());
                    tWaybillTracke.setCaptureTime(tLocationData.getCaptureTime());
                    tWaybillTracke.setCityCode(tLocationData.getCityCode());
                    tWaybillTracke.setCityName(tLocationData.getCityName());
                    tWaybillTracke.setSpeed(tLocationData.getSpeed());
                    tWaybillTracke.setTemperature(tLocationData.getTemperature());
                    tWaybillTracke.setBattery(tLocationData.getBattery());
                    tWaybillTracke.setReportDay(tLocationData.getDateOfDay());
                    tWaybillTracke.setIsMove(tLocationData.getIsMove());
                    tWaybillTracke.setLocateWay(tLocationData.getLocatWay());
                    tWaybillTracke.setLocationId(tLocationData.getId());
                    tWaybillTrackeMapper.insertTWaybillTracke(tWaybillTracke);
                }
            }
        } catch (Exception e) {
            // 处理异常
            e.printStackTrace();
        }
    }
}
